﻿#include "pila.h"
#include <stdio.h>
#include <stdlib.h>


struct _pila{

	void** datos;    
	size_t tamanio;
    size_t cantidad;
};

// Crea una pila.

// Post: devuelve una nueva pila vacía.

pila_t* pila_crear()
{	
	
   pila_t* _pila = malloc(sizeof(pila_t));
 
   if (_pila == NULL) {
		return NULL;
   }
   _pila->tamanio = 15;
   _pila->cantidad = 0;

   _pila->datos =malloc(_pila->tamanio * sizeof(void*));
   if (_pila->datos == NULL){

      free(_pila);
      return NULL;
   }

   return _pila;

}


// Destruye la pila.

// Pre: la pila fue creada.

// Post: se eliminaron todos los elementos de la pila.

void pila_destruir(pila_t *pila){

   free(pila->datos);
   free (pila);

}

// Devuelve verdadero o falso, según si la pila tiene o no elementos apilados.

// Pre: la pila fue creada.

bool pila_esta_vacia(const pila_t *pila){
	return (pila->cantidad==0);
}

// Obtiene el valor del tope de la pila. Si la pila tiene elementos,

// se devuelve el valor del tope. Si está vacía devuelve NULL.

// Pre: la pila fue creada.

// Post: se devolvió el valor del tope de la pila, cuando la pila no está

// vacía, NULL en caso contrario.

void* pila_ver_tope(const pila_t *pila){
   if (pila_esta_vacia(pila)){

      return NULL;
	  
   }
 
   return pila->datos[(pila->cantidad)-1];

}




// Agrega un nuevo elemento a la pila. Devuelve falso en caso de error.

// Pre: la pila fue creada.

// Post: se agregó un nuevo elemento a la pila, valor es el nuevo tope.

bool pila_apilar(pila_t *pila, void* valor){

   //aca va el error si no se puede hacer realloc en caso de que la pila este llena

   pila->cantidad++;
   if(pila->tamanio==pila->cantidad){
	   void** datoaux=realloc(pila->datos,pila->tamanio*2*sizeof(void*));
	   if(!datoaux)return false;
	   pila->tamanio=pila->tamanio*2;
	   pila->datos=datoaux;	   
	}

   pila->datos[(pila->cantidad)-1]=valor;

   //si se utilizo el espacio asignado, asigno mas espacio de memoria

   if ((pila->tamanio-pila->cantidad)==0){

	  void* aux = realloc(pila->datos, pila->tamanio * sizeof(void*));
	  if(aux==NULL){		//Ver si van estas dos lineas
		free(pila);
		return false;
      }else{
		//para asignar la memoria que estaba en realocando
		pila->datos = aux;
		pila->tamanio+= 15;

	 }
   }
   
   if (pila->datos == NULL){

      free(pila);
      return false;
   }
   return true;
}

// Saca el elemento tope de la pila. Si la pila tiene elementos, se quita el

// tope de la pila, y se devuelve ese valor. Si la pila está vacía, devuelve 

// NULL.

// Pre: la pila fue creada.

// Post: si la pila no estaba vacía, se devuelve el valor del tope anterior
// y la pila contiene un elemento menos.

void* pila_desapilar(pila_t *pila){
   if (pila_esta_vacia(pila)){
      return NULL;
   }
   void* resultado=pila->datos[(pila->cantidad)-1];
   pila->cantidad--;
   return resultado;

}
